/*
 * Copyright (C), 2015-2018
 * FileName: Solution061
 * Author:   zhao
 * Date:     2018/12/12 19:53
 * Description: 61. 旋转链表
 * History:
 * <author>          <time>          <version>          <desc>
 * 作者姓名           修改时间           版本号              描述
 */
package com.lizhaoblog.mid;

import com.lizhaoblog.diynode.ListNode;

/**
 * 〈一句话功能简述〉<br>
 * 〈61. 旋转链表〉
 *
 * @author zhao
 * @date 2018/12/12 19:53
 * @since 1.0.0
 */
public class Solution061 {
  /**************************************
   * 题目
   给定一个链表，旋转链表，将链表每个节点向右移动 k 个位置，其中 k 是非负数。

   示例 1:

   输入: 1->2->3->4->5->NULL, k = 2
   输出: 4->5->1->2->3->NULL
   解释:
   向右旋转 1 步: 5->1->2->3->4->NULL
   向右旋转 2 步: 4->5->1->2->3->NULL
   示例 2:

   输入: 0->1->2->NULL, k = 4
   输出: 2->0->1->NULL
   解释:
   向右旋转 1 步: 2->0->1->NULL
   向右旋转 2 步: 1->2->0->NULL
   向右旋转 3 步: 0->1->2->NULL
   向右旋转 4 步: 2->0->1->NULL
   **************************************/

  /*************************************
   想法：
   先把链表编程一个环，然后算出要移动的位数(k%length)，

   把头位置往后移k位，把头位置的前一位的下一位变成null

   比如： 12345null，-->   1234512345123...
   这时候头位置还是1，往后移动k，头位置变成4，头位置的前一位3的下一位变成null，
   结果就是45123null

   我的做法
   超过98%的测试案例
   时间复杂度/空间复杂度：n/1
   代码执行过程：

   总结：

   ************************************/
  public ListNode rotateRight(ListNode head, int k) {
    if (head == null || head.next == null) {
      return head;
    }
    // 链表长度
    int count = 1;
    ListNode cur = head;
    while (cur.next != null) {
      ++count;
      cur = cur.next;
    }
    // 下一一步结束之后，已经首位相连了，
    cur.next = head;
    // 判断要移动的个数
    count = count - k % count;
    for (int i = 0; i < count; ++i) {
      cur = cur.next;
    }
    ListNode newhead = cur.next;
    cur.next = null;
    return newhead;
  }

  /**************************************
   * 比我好的答案 better
   * ***********************************/
  public ListNode better(ListNode head, int k) {
    if (head == null) {
      return null;
    }
    ListNode p = head;
    int n = 0;
    while (p != null) {
      n++;
      p = p.next;
    }
    k = k % n;
    p = head;
    for (int i = 0; i < k; i++) {
      p = p.next;
    }
    ListNode slow = head;
    while (p.next != null) {
      p = p.next;
      slow = slow.next;
    }
    p.next = head;
    p = slow.next;
    slow.next = null;

    return p;
  }

}